#include "mainwindow.h"
#include "settingwindow.h"
#include "shortcuteditdialog.h"
#include <DDesktopEntry>
#include <DMessageBox>
#include <DTitlebar>
#include <DWidgetUtil>
#include <QAbstractItemView>
#include <QDesktopServices>
#include <QFileInfo>
#include <QIcon>
#include <QInputDialog>
#include <QMimeData>
#include <QMimeDatabase>
#include <QSize>
#include <QString>
#include <QWidget>

DWIDGET_USE_NAMESPACE

using namespace Dtk::Core;
#define Tag Qt::UserRole

MainWindow::MainWindow(DMainWindow *parent) : DMainWindow(parent) {

  auto myico = QIcon(":/logo.ico");
  // init the MainWindow
  MainWindow::resize(QSize(500, 500));
  this->setAcceptDrops(true);
  this->setWindowIcon(myico);
  this->setWindowFlag(Qt::WindowMaximizeButtonHint, false);

  w = new QWidget;

  auto title = titlebar();
  title->setTitle("Maye");
  title->setIcon(myico);
  setCentralWidget(w);

  // init the controls

  listcat = new DListWidget;
  listcat->setFixedWidth(150);
  listcat->setContextMenuPolicy(Qt::CustomContextMenu);
  listcat->setItemAlignment(Qt::AlignCenter);
  listcat->setDragDropMode(QAbstractItemView::InternalMove);

  listitems = new DListWidget;
  listitems->setDragDropMode(QAbstractItemView::InternalMove);
  listitems->setIconSize(QSize(40, 40));

  layui = new QHBoxLayout(w);
  layui->setSpacing(0);
  layui->addWidget(listcat);
  layui->addWidget(listitems);

  // menucat
  menucat = new QMenu(listcat);

  QAction *paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "NewCat")));
  connect(paction, &QAction::triggered, this, &MainWindow::on_newcat_triggered);
  menucat->addAction(paction);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "Rename")));
  connect(paction, &QAction::triggered, this, &MainWindow::on_rncat_triggered);
  menucat->addAction(paction);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "DelCat")));
  connect(paction, &QAction::triggered, this, &MainWindow::on_delcat_triggered);
  menucat->addAction(paction);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "DelClr")));
  connect(paction, &QAction::triggered, this, &MainWindow::on_clrcat_triggered);
  menucat->addAction(paction);

  // menuitem
  menuitem = new QMenu(listitems);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "NewItem")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_newitem_triggered);
  menuitem->addAction(paction);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "EditItem")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_edititem_triggered);
  menuitem->addAction(paction);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "DelItem")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_delitem_triggered);
  menuitem->addAction(paction);

  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "ClrItem")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_clritem_triggered);
  menuitem->addAction(paction);

  // menutitle
  menutitle = new QMenu(this);
  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "Setting")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_setting_triggered);
  menutitle->addAction(paction);

  title->setMenu(menutitle); // set the title menu

  // construct the connections
  connect(DGuiApplicationHelper::instance(),
          &DGuiApplicationHelper::themeTypeChanged, this,
          &MainWindow::setTheme);

  connect(listcat, &QListWidget::customContextMenuRequested, this,
          &MainWindow::on_show_catMenu);
  connect(listcat, &QListWidget::itemClicked, this,
          &MainWindow::on_listcat_itemClicked);
  connect(listcat, &QListWidget::itemSelectionChanged, this,
          &MainWindow::on_listcat_itemSelectionChanged);

  connect(listitems, &QListWidget::itemClicked, this,
          &MainWindow::on_listItems_itemClicked);
  connect(listitems, &QListWidget::itemPressed, this,
          &MainWindow::on_listItems_itemPressed);
  connect(listitems, &QListWidget::customContextMenuRequested, this,
          &MainWindow::on_show_itemsMenu);

  // init the menu of systray
  menusys = new QMenu;
  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "Setting")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_setting_triggered);
  menusys->addAction(paction);
  paction = new QAction(TRANS(QT_TRANSLATE_NOOP("MWND", "Exit")));
  connect(paction, &QAction::triggered, this,
          &MainWindow::on_menuexit_triggered);
  menusys->addAction(paction);

  // add the systray
  systray = new QSystemTrayIcon;
  systray->setIcon(myico);
  systray->setToolTip("Maye");
  systray->setContextMenu(menusys);
  systray->setVisible(true);
}

MainWindow::~MainWindow() {
  systray->setVisible(false);
  delete systray;
  delete menucat;
  delete menuitem;
  delete listitems;
  delete listcat;
  delete layui;
  delete w;
}

void MainWindow::setTheme(DGuiApplicationHelper::ColorType theme) {
  if (theme == DGuiApplicationHelper::LightType) {

  } else {
  }
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event) {
  if (event->mimeData()->hasUrls()) {
    event->acceptProposedAction();
  } else
    event->ignore();
}

void MainWindow::dropEvent(QDropEvent *event) {
  const QMimeData *mineData = event->mimeData();
  if (mineData->hasUrls()) {
    QList<QUrl> urlList = mineData->urls();
    if (urlList.isEmpty())
      return;
    for (auto item : urlList) {
      ShortCutInfo info;
      parse(item, info);
      info.Catagory = curCat;
      addshortcut(info);
      QListWidgetItem *r = new QListWidgetItem;
      QIcon ico = QIcon::fromTheme(info.Icon, QIcon(info.Icon));
      r->setIcon(ico);
      r->setText(info.Name);
      r->setToolTip(info.Comment);
      r->setData(Tag, QVariant::fromValue(info));

      listitems->addItem(r);
    }
  }
}

void MainWindow::on_menuexit_triggered(bool checked) { close(); }

void MainWindow::parse(QUrl item, ShortCutInfo &r) {
  QString fileName = item.toLocalFile();
  if (fileName.isEmpty())
    return;

  QMimeDatabase db;
  auto mt = db.mimeTypeForFile(fileName);
  auto n = mt.name();

  if (n == "application/x-desktop" && fileName.endsWith(".desktop")) {
    DDesktopEntry d(fileName);
    r.Name = d.name();
    r.Icon = d.stringValue("Icon");
    r.Filename = d.stringValue("Exec");
    r.isExec = true;
    r.Comment = d.comment();
  } else {
    r.isExec = (n == "application/x-executable");
    r.Icon = mt.iconName();
    QFileInfo fi(fileName);
    r.Name = fi.fileName();
    r.Filename = "file://" + fi.absoluteFilePath();
  }
}

void MainWindow::on_listItems_itemClicked(QListWidgetItem *item) {

  auto info = item->data(Tag).value<ShortCutInfo>();
  if (info.isExec) {
    QStringList args;
    args << "-c" << info.Filename;
    if (!pstart.startDetached("/bin/sh", args)) {
      DMessageBox::critical(this, TRANS(QT_TRANSLATE_NOOP("MWND", "runErr")),
                            pstart.errorString());
    }
  } else {
    if (!QDesktopServices::openUrl(QUrl(info.Filename))) {
      DMessageBox::critical(this, TRANS(QT_TRANSLATE_NOOP("MWND", "err")),
                            TRANS(QT_TRANSLATE_NOOP("MWND", "openErr")));
    }
  }

  listitems->clearSelection();
}

void MainWindow::on_listcat_itemClicked(QListWidgetItem *item) {}

void MainWindow::on_show_catMenu(const QPoint &p) {
  Q_UNUSED(p)
  menucat->move(cursor().pos());
  menucat->show();
}

void MainWindow::on_show_itemsMenu(const QPoint &p) {
  Q_UNUSED(p)
  menuitem->move(cursor().pos());
  menuitem->show();
}

void MainWindow::on_newcat_triggered(bool checked) {
  Q_UNUSED(checked)
  QInputDialog indlg;
  indlg.setWindowTitle(TRANS(QT_TRANSLATE_NOOP("MWND", "New")));
  indlg.setLabelText(TRANS(QT_TRANSLATE_NOOP("MWND", "InputCatName")));
  indlg.setModal(true);
  if (indlg.exec()) {
    auto v = indlg.textValue();
    catagories << v;
    QListWidgetItem *item = new QListWidgetItem;
    item->setText(v);
    item->setTextAlignment(Qt::AlignCenter);
    item->setSizeHint(QSize(listcat->width(), 50));
    listcat->addItem(item);
    item->setSelected(true);
  }
}

void MainWindow::on_listItems_itemPressed(QListWidgetItem *item) {}

void MainWindow::on_newitem_triggered(bool checked) {
  Q_UNUSED(checked)
  if (catagories.isEmpty()) {
    DMessageBox::warning(this, TRANS(QT_TRANSLATE_NOOP("MWND", "warn")),
                         TRANS(QT_TRANSLATE_NOOP("MWND", "NoCat")));
    return;
  }
}

void MainWindow::addshortcut(ShortCutInfo si) {
  QList<ShortCutInfo> *scs;

  if (shortcuts.contains(si.Catagory)) {
    scs = shortcuts.value(si.Catagory);
  } else {
    if (!catagories.contains(si.Catagory))
      return;
    scs = new QList<ShortCutInfo>;
    shortcuts.insert(si.Catagory, scs);
  }
  scs->append(si);
}

void MainWindow::on_edititem_triggered(bool checked) { Q_UNUSED(checked) }
void MainWindow::on_delitem_triggered(bool checked) { Q_UNUSED(checked) }
void MainWindow::on_clritem_triggered(bool checked) { Q_UNUSED(checked) }

void MainWindow::on_delcat_triggered(bool checked) { Q_UNUSED(checked) }
void MainWindow::on_clrcat_triggered(bool checked) { Q_UNUSED(checked) }
void MainWindow::on_rncat_triggered(bool checked) { Q_UNUSED(checked) }
void MainWindow::on_listcat_itemSelectionChanged() {

  listitems->clear();

  if (listcat->count() == 0)
    curCat = listcat->selectedItems().at(0)->text();

  if (shortcuts.contains(curCat)) {
    auto p = shortcuts.value(curCat);
    QListWidgetItem *c;
    for (ShortCutInfo item : *p) {
      c = new QListWidgetItem;
      c->setSizeHint(QSize(listitems->width(), 40));
      c->setText(item.Name);
      QIcon ico = QIcon::fromTheme(item.Icon, QIcon(item.Icon));
      c->setIcon(ico);
      c->setData(Tag, QVariant::fromValue(item));
      c->setToolTip(item.Comment);
      listitems->addItem(c);
    }
  }
}

void MainWindow::on_setting_triggered(bool checked) {
  SettingWindow setting(this);
  setting.exec();
}
